Skip to content

Add Teredo (RFC4380) embedding strategy#109

Merged
zanbaldwin merged 1 commit into
6.xfrom
z/teredo
Jun 8, 2026
Merged

Add Teredo (RFC4380) embedding strategy#109
zanbaldwin merged 1 commit into
6.xfrom
z/teredo

Conversation

@zanbaldwin

Copy link
Copy Markdown
Member

No description provided.

@greptile-apps

greptile-apps Bot commented Jun 5, 2026

Copy link
Copy Markdown

Greptile Summary

This PR adds a Teredo embedding strategy (src/Strategy/Teredo.php) that extracts and packs IPv4 addresses according to RFC 4380 § 4, matching the 2001:0000::/32 prefix and XOR-obfuscating the client IPv4 in the last 32 bits. It follows the established pattern of the existing Mapped, Derived, and Nat64 strategies.

  • Strategy implementation (src/Strategy/Teredo.php): isEmbedded checks the 32-bit Teredo prefix, extract XORs bytes 12–15 with 0xFFFFFFFF per the RFC, and pack constructs the canonical Teredo form (zero server/flags/port). The documented asymmetry between extraction and packing for non-canonical addresses is intentional and matches the Derived strategy's behaviour.
  • Test data (tests/DataProvider/Strategy/Teredo.php): Vectors are verified against the RFC 4380 worked example (server 65.54.227.120, client 192.0.2.45) and cover canonical, non-canonical, and loopback-embedding cases.
  • IpDataProviderInterface bit-flag renumbering: TEREDO = 1 << 26 is inserted between COMPATIBLE and the existing LOOPBACK_* group, shifting LOOPBACK_MAPPED/COMPATIBLE/DERIVED each up by one bit. These are test-internal constants referenced only by name, so the shift is safe.

Confidence Score: 5/5

The change is self-contained and additive — new strategy class, new test data provider, and one new test method; no existing production paths are modified.

The Teredo prefix check, XOR extraction, and canonical packing all match RFC 4380 § 4 and are verified against the RFC's own worked example. The bit-flag renumbering in the test interface is safe because every usage references the constants by name. The related ip-doctrine library makes no reference to embedding strategies and is unaffected.

No files require special attention.

Important Files Changed

Filename Overview
src/Strategy/Teredo.php New Teredo embedding strategy; prefix check, XOR extraction, and canonical packing are all correct per RFC 4380 § 4, and consistent with the rest of the strategy layer.
tests/DataProvider/Strategy/Teredo.php Test vectors verified against the RFC 4380 worked example; covers canonical, non-canonical, and loopback-embedding cases.
tests/DataProvider/IpDataProviderInterface.php TEREDO (1 << 26) and LOOPBACK_TEREDO (1 << 30) added, existing LOOPBACK_* constants shifted up one bit; safe because all usages reference constants by name, not numeric value.
tests/Strategy/TeredoTest.php Full unit test coverage for isEmbedded, extract, and pack; consistent with other strategy tests in the suite.
tests/Version/MultiTest.php Adds testIsLoopbackTeredo to verify that Multi::isLoopback() correctly delegates through the Teredo strategy for addresses embedding 127.0.0.1.

Sequence Diagram

sequenceDiagram
    participant Caller
    participant Teredo as Strategy\Teredo
    participant Binary as Util\Binary
    participant MbString as Util\MbString

    note over Caller,MbString: isEmbedded - prefix detection
    Caller->>Teredo: isEmbedded(binary)
    Teredo->>MbString: "getLength(binary) == 16?"
    Teredo->>MbString: subString(binary, 0, 4)
    Teredo->>Binary: fromHex('20010000')
    Teredo-->>Caller: "true if first 4 bytes == 2001:0000"

    note over Caller,MbString: extract - client IPv4 recovery
    Caller->>Teredo: extract(binary)
    Teredo->>MbString: "getLength(binary) == 16?"
    Teredo->>MbString: subString(binary, 12, 4)
    note right of Teredo: XOR last 4 bytes with 0xFFFFFFFF
    Teredo-->>Caller: 4-byte client IPv4

    note over Caller,MbString: pack - canonical Teredo construction
    Caller->>Teredo: pack(ipv4binary)
    Teredo->>MbString: "getLength(ipv4binary) == 4?"
    Teredo->>Binary: fromHex('20010000') prefix
    Teredo->>Binary: fromHex('0000000000000000') zeroed fields
    note right of Teredo: XOR IPv4 with 0xFFFFFFFF
    Teredo-->>Caller: 16-byte canonical Teredo address
Loading

Reviews (2): Last reviewed commit: "feature(strategy): ✨ add Teredo (RFC4380..." | Re-trigger Greptile

Comment thread docs/05-strategies.md Outdated
Unfortunately there are several different strategies for embedding a version 4
address into version 6, so this library offers various strategy implementations
for the main three:
for the main three (and one deprecated):

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 The prose says "the main three (and one deprecated)" but the table now has four entries. The parenthetical also never identifies which strategy is deprecated (IPv4-compatible, per RFC 4291 §2.5.5.1). Consider updating the sentence to count accurately and name the deprecated strategy.

Suggested change
for the main three (and one deprecated):
for four strategies (the IPv4-compatible strategy is deprecated per RFC 4291):

@zanbaldwin zanbaldwin added the feature New feature (minor version bump) label Jun 7, 2026
@zanbaldwin zanbaldwin merged commit 941a445 into 6.x Jun 8, 2026
24 checks passed
@zanbaldwin zanbaldwin deleted the z/teredo branch June 8, 2026 20:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New feature (minor version bump)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant